import React, {useEffect, useState} from "react";
import {Table, TreeSelect, Select, Checkbox} from 'antd';
import _uniqBy from 'lodash/uniqBy';
import _isEmpty from 'lodash/isEmpty';
import styles from './UserTaskObject.less'

const {Option} = Select
const UserTaskObject = (props) => {

  const {dispatch, handleChangeProperties, selectedModel = {}, modelProperties} = props;
  const [treeSelectedSource, setTreeSelectedSource] = useState([]);
  const [treeSelectedValue, setTreeSelectedValue] = useState();
  const [currentItem, setCurrentItem] = useState({});
  const [dataSource, setDataSource] = useState([]);
  const [selectSource, setSelectSource] = useState([]);
  const [selectedValue, setSelectedValue] = useState();


  useEffect(() => {
    getObjItem('ROOT', true);

  }, []);

  useEffect(() => {
    let objectMeta = modelProperties.objectMeta ?? {};

    // 节点拥有自己的 objectMeta
    const hasObjectMeta = !_isEmpty(selectedModel?.model?.properties?.objectMeta);
    if (hasObjectMeta) {
      objectMeta = selectedModel?.model?.properties?.objectMeta ?? {};
    } else {
      handleChangeProperties(
        'objectMeta',
        objectMeta,
        selectedModel?.model,
        selectedModel?.shape,
        false,
      );
    }

    const { layout = { name: '' }, code = '', attributes = [], ...rest } = objectMeta;
    if (!_isEmpty(code)) {
      setCurrentItem({code, attributes, ...rest});
      setTreeSelectedValue(code);
      setSelectedValue(layout.name);
      setDataSource()
    }

  }, [selectedModel]);


  useEffect(() => {
    const {attributes = []} = currentItem;
    setDataSource(attributes);

  }, [currentItem]);


// 属性Key	属性名称	描述	类型
  const columns = [
    {
      title: '属性名称',
      ellipsis: true,
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: '属性编码',
      ellipsis: true,
      dataIndex: 'code',
      key: 'code',
    },
    {
      title: '查看',
      dataIndex: 'visible',
      key: 'visible',
      render: (text, record) => (
        <Checkbox
          checked={text}
          onChange={(e) => handleChecked(
            record, 'visible',
            e.target.checked)}
        />
      ),
    },
    {
      title: '编辑',
      dataIndex: 'editable',
      key: 'editable',
      render: (text, record) => (
        <Checkbox
          checked={text}
          onChange={(e) => handleChecked(
            record, 'editable',
            e.target.checked)}
        />
      ),
    },
    {
      title: '必填',
      dataIndex: 'required',
      key: 'required',
      render: (text, record) => (
        <Checkbox
          checked={text}
          onChange={(e) => handleChecked(
            record, 'required',
            e.target.checked)}
        />
      ),
    },
  ]

  const defaultLayout = [
    {
      code: 'oid',
      name: 'OID',
      type: 'Int',
    },
    {
      code: 'number',
      name: '对象编号',
      type: 'String',
    },
    {
      code: 'version',
      name: '对象版本',
      type: 'String',
    },
    {
      code: 'name',
      name: '对象名称',
      type: 'String',
    },
    {
      code: 'objectMetaCode',
      name: '类型编码',
      type: 'String',
    },

    {
      code: 'objectMetaVersion',
      name: '类型版本',
      type: 'Int',
    },

    {
      code: 'containerCode',
      name: '容器编码',
      type: 'String',
    },

    {
      code: 'containerName',
      name: '容器名称',
      type: 'String',
    },

    {
      code: 'lifecycleTemplateCode',
      name: '生命周期模板编码',
      type: 'String',
    },

    {
      code: 'lifecycleTemplateVersion',
      name: '生命周期模板版本',
      type: 'Int',
    },

    {
      code: 'lifecycleTemplateName',
      name: '生命周期模板名称',
      type: 'String',
    },
    {
      code: 'lifecycleStatusCode',
      name: '生命周期状态编码',
      type: 'String',
    },
    {
      code: 'lifecycleStatusName',
      name: '生命周期状态名称',
      type: 'String',
    },
    {
      code: 'mainContentId',
      name: '主内容 ID',
      type: 'Int',
    },
    {
      code: 'attachmentIds',
      name: '附件 ID 列表',
      type: 'Int',
    },

    {
      code: 'teamInstanceId',
      name: '团队实例 ID',
      type: 'Int',
    },
  ]

  const handleChecked = (record, type, value) => {
    dataSource.map(item => {
      if (item.code === record.code) {
        item[type] = value;
      }
      return item;
    })

    currentItem.attributes = dataSource;
    setCurrentItem(currentItem);
    handlePropertiesChange(selectedValue, currentItem);
  }

  const handlePropertiesChange = (e, changeItem) => {
    let layout = {};
    if (!_isEmpty(selectedModel?.model?.properties?.objectMeta)) {
      layout = selectedModel?.model?.properties?.objectMeta?.layout ?? {};
    } else {
      layout = modelProperties.objectMeta?.layout ?? {}
    }
    selectSource.map(item => {
      if (item.name === e) {
        layout = item;
      }
      return item;
    })

    const tmpValue = {...changeItem, layout};
    handleChangeProperties(
      'objectMeta',
      tmpValue,
      selectedModel?.model,
      selectedModel?.shape,
      false,
    );
  }

  const handleChange = (e) => {
    setSelectedValue(e);
    handlePropertiesChange(e, currentItem);
  }

  const handleTreeSelectChange = (value) => {

    setTreeSelectedValue(value);
    setSelectedValue('');
    getObjItem(value, false);
    if (!value) {
      setCurrentItem({});
      handleChangeProperties(
        'objectMeta',
        {},
        selectedModel?.model,
        selectedModel?.shape,
        false,
      );
    }

  }

  const getObjItem = (code = '', isFirst) => {
    if (_isEmpty(code)) return;
    dispatch({
      type: 'ObjectSource/getObjectList',
      payload: code,
    }).then(res => {
      const {datas = {}, errCode} = res;

      if (errCode !== 0) {
        return;
      }

      getLayout(datas?.code, datas?.version);

      const {children = [], attributes = []} = datas;
      let tmpValues = children.map(item => {
        const {code: code1, name, parentCode, childCount, ...rest1} = item;

        return {
          ...rest1,
          code: code1, name, parentCode, childCount,
          children: [],
          id: code1,
          value: code1,
          pId: parentCode,
          title: name,
          isLeaf: childCount === 0,
        }
      })

      tmpValues = _uniqBy(tmpValues, 'code');

      let tmpList = _uniqBy([...tmpValues, ...treeSelectedSource, {
        ...datas,
        id: datas?.code,
        value: datas?.code,
        pId: datas?.parentCode,
        title: datas?.name,
        isLeaf: datas?.childCount === 0,
      }], 'code');

      tmpList = tmpList.map(item => {

        return {...item, children: []};
      })

      setTreeSelectedSource(tmpList);

      let tmpAttributes = []
      if (attributes.length > 0) {
        tmpAttributes = [...defaultLayout, ...attributes].map(attributesItem => {

          return {
            ...attributesItem,
            visible: true,
            editable: false,
            required: false,
          }
        })
      }

      if (!isFirst) {

        const tmpItem = {
          ...datas,
          attributes: tmpAttributes,
          id: datas?.code,
          value: datas?.code,
          pId: datas?.parentCode,
          title: datas?.name,
          isLeaf: datas?.childCount === 0,
        };
        setCurrentItem(tmpItem);
        handlePropertiesChange(selectedValue, tmpItem);
      }

    })
  }

  const getLayout = (metaCode = '', metaVersion = '') => {
    if (_isEmpty(metaCode)) return;

    dispatch({
      type: 'ObjectSource/getObjectLayout',
      payload: {metaVersion, metaCode},
    }).then(res => {
      const {datas = []} = res;
      setSelectSource(datas)
    });
  }

  const onLoadData = treeNode =>
    new Promise(resolve => {
      const {code} = treeNode.props;

      dispatch({
        type: 'ObjectSource/getObjectList',
        payload: code,
      }).then(res => {

        const {datas = {}} = res;
        const {children = [], ...rest} = datas;
        let tmpValues = children.map(item => {
          const {code: code1, name, parentCode, childCount} = item;

          return {
            ...item,
            id: code1, value: code1, pId: parentCode, title: name, isLeaf: childCount === 0,
          }
        })
        tmpValues = _uniqBy(tmpValues, 'code');

        let tmpList = _uniqBy([...treeSelectedSource, ...tmpValues, {
          ...rest,
          id: datas?.code,
          value: datas?.code,
          pId: datas?.parentCode,
          title: datas?.name,
          isLeaf: datas?.childCount === 0,
        }], 'code');

        tmpList = tmpList.map(item => {

          return {...item, children: []};
        })
        setTreeSelectedSource(tmpList);


        resolve();
      })

    });

  return (
    <div className={styles.root}>
      <div className={styles.title}>对象类型</div>
      <TreeSelect
        style={{width: '100%'}}
        defaultValue={treeSelectedValue}
        value={treeSelectedValue}
        treeData={treeSelectedSource}
        dropdownStyle={{maxHeight: 400, overflow: 'auto'}}
        placeholder="请选择"
        allowClear
        loadData={onLoadData}
        treeDataSimpleMode
        onChange={handleTreeSelectChange}
      />


      <div className={styles.title}>布局</div>
      <Select
        allowClear
        value={selectedValue}
        style={{width: '100%'}}
        onChange={handleChange}
      >
        {selectSource.map(item => {
          return <Option key={item.name} value={item?.name}>{item?.name}</Option>
        })}
      </Select>

      <Table
        style={{marginTop: '10px'}}
        columns={columns}
        dataSource={dataSource}
        pagination={false}
      />
    </div>
  )
}

export default UserTaskObject;
